package com.ym521.logdog.utils

/**
 *自定义 占位符和解析占位符
 */
object LogFormatUtil {
    /**
     * 支持的占位符
     */
    private const val FORMAT_LOG = "%log"


    fun toLogContent(logContent: String, vararg objArray: Any): String {
        val findList = findPlaceholder(logContent)
        return replacePlaceholder(logContent, findList, *objArray)
    }

    /**
     * 占位符替换
     */
    private fun replacePlaceholder(
        logContent: String,
        findList: List<Int>,
        vararg objArray: Any
    ): String {
        if (findList.size > objArray.size) {
            throw RuntimeException("The number of placeholders is lower than the number of placeholder variables!")
        }
        val newContent = logContent.replace(FORMAT_LOG, "")
        val stringBuilder = StringBuilder(newContent)
        for (index in findList.indices) {
            val contentIndex = findList[index] - ((index) * FORMAT_LOG.length) + montageLength(
                index,
                *objArray
            )
            stringBuilder.insert(contentIndex, objArray[index].toString())
        }
        return stringBuilder.toString()
    }

    /**
     * 获取占位符的位置
     * 这个位置不是绝对位置是相对位置
     */
    private fun findPlaceholder(logContent: String): List<Int> {
        val indexList = mutableListOf<Int>()
        if (logContent.contains(FORMAT_LOG)) {
            var findIndexSum = 0
            while (true) {
                val index = logContent.indexOf(FORMAT_LOG, findIndexSum, false)
                if (index == -1) {
                    break
                }
                indexList.add(index)
                findIndexSum = index + 3
                if (findIndexSum >= logContent.length) {
                    break
                }
            }
        }
        return indexList
    }

    /**
     * 拼接字符串取长度
     * endIndex的前一位截止
     */
    private fun montageLength(endIndex: Int, vararg objArray: Any): Int {
        var str = ""
        for (i in objArray.indices) {
            if (i == endIndex) {
                break
            }
            str += objArray[i].toString()
        }
        return str.length
    }

}